跳到主要内容

kubernetes 1.25.4 在 Anolis 8 RHEL 的集群部署指引

注意

由于这个页面的内容是从 Jimmy 的语雀的笔记 迁移过来的,所以格式会存在一些问题。 因为大部分内容都可以正常阅读,我会在有空的时候将文章格式修正。

虽然写这篇文章的时候 K8S 1.25 才刚刚发布,但你看到这篇文章的时候可能版本已经过时了。Jimmy 仍然在对 K8S 的部署以及使用做更深入的研究,但受限于时间和设备资源问题暂时没有公开关于 K8S 更多的文章。

这个教程主要在龙蜥 Anolis 系统上部署 k8s 集群,与 Dashboard,参考多方大佬文章经过数天若干次试验成功部署。经过实验本文也适应于 CentOS 8 任意版本。
[@Jimmy Kmi(jimmy-2ueqc)** Jimmy 版权所有 转发时请署名作者(文档界的 Apache 2.0)]**

前言

如果你不清楚 k8s 是做什么的,技术源是什么公司的,那么此文大概率不会对您有任何帮助。

为什么研究 k8s

本人是学大数据专业的,常用到的 spark、hadoop 也是需要集群运行,但是用于生产环境的时候无论是服务器资费还是效率都令人头秃,在网上考证是可以通过 k8s 承载 hadoop 集群,并且部署 spark,所以就有了这篇教程。后面需要调用 Q# 运行量子运算时也希望能够有办法通过 k8s 进行集群调度(已经写入计划但未提上日程)。

为什么选择新版

由于 k8s 在 1.25 版本对 docker 的支持方式有较大变化,所以提前把未来部分坑踩了。目前最新版是 1.25.4,按照旧版保无 bug 的情况下不建议在生产环境使用。但本人对新技术比较激进,目前就是为了部署在个人网站的生产环境。但是云效平台暂时只支持到 build 1.23,所以后面整理完会更新 1.23 的教程。

阿里云

阿里云有现成的,入门成本太高,要求基础配置过高、k8s 部署另外收取服务费。但本试验因为需要对系统重装、备份无数次,所以阿里云 ECS 能为我节约不少时间,我也花了不少钱在 ECS 上进行测试。 参考过大部分的部署方法,坑点都比较集中,这篇文章在于通过试验解决不少坑点。

国内网络

中国大陆的网络无法访问谷歌,但k8s的大多源都是谷歌,githubraw的网址也经常被污染,所以k8s的源已大部分使用阿里云源,githubraw如果遇到失败请修改host或重试。

基本要求

注意,本文会忽略以下内容:

  1. HOST,这东西实在是太不优雅,进行任何修改需要所有节点同步,解决方案是私有 DNS域,本文使用 k8s.zone,这方面介绍会在以后补充,这里不作过多赘述。
  2. IP,这东西也非常不优雅,IP 地址在路由端固定。与 DNS 可以同域控。
  3. 防火墙,单服务器配置不优雅,统一在路由端做防火墙。

配置

Anolis OS 8 RHCL 2核心 4G内存 (main) Anolis OS 8 RHCL 2核心 2G内存 (node) * n

版本

kubernetes 1.25.4 (1.25.x 通用)
Dashboard 2.6.1
Golang 1.18.8
runc 1.1.4
libeseccomp 2.5.2
ctr 1.6.10
registry.k8s.io/kube-apiserver:v1.25.4
registry.k8s.io/kube-controller-manager:v1.25.4
registry.k8s.io/kube-scheduler:v1.25.4
registry.k8s.io/kube-proxy:v1.25.4
registry.k8s.io/pause:3.8
registry.k8s.io/etcd:3.5.5-0
registry.k8s.io/coredns/coredns:v1.9.3

Bare Metal 安装

注意,这一步会关闭防火墙、selinux 如果是无防火服务器请留意。防火墙不是必须关闭的,但是需要给 k8s 预留。如果是局域网安装或使用安全组。此步骤可以快速复制粘贴执行。 此步骤全部节点执行

# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# 关闭所有防火墙(使用安全组)
systemctl stop firewalld
systemctl disable firewalld

# 关闭swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 系统优化
cat > /etc/sysctl.d/k8s_better.conf << EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
modprobe br_netfilter
lsmod |grep conntrack
modprobe ip_conntrack
sysctl -p /etc/sysctl.d/k8s_better.conf

# 系统依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset iproute-tc jq iptables curl sysstat libseccomp wget vim net-tools git
# bash 自补充 (阿里云自带,非托管机构自行加料)
# sudo yum -y install bash-completion
# source /etc/profile

# 时间同步,开机启动 (阿里云自带,非托管机自行加料)
# sudo ntpdate ntp1.aliyun.com
# sudo systemctl status ntpdate
# sudo systemctl start ntpdate
# sudo systemctl status ntpdate
# sudo systemctl enable ntpdate

# 关闭 selinux
getenforce
cat /etc/selinux/config
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
cat /etc/selinux/config

# 开启ipvs 转发
modprobe br_netfilter

cat <<EOF >/etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules

bash /etc/sysconfig/modules/ipvs.modules

lsmod | grep -e ip_vs -e nf_conntrack

# 确保每台机器的uuid不一致,如果是克隆机器,修改网卡配置文件删除uuid那一行
# cat /sys/class/dmi/id/product_uuid

image.png

添加 阿里云镜像仓库

这里使用了阿里云节点,国内外均可使用,若在国外机房可以使用k8s源。 此步骤全部节点执行

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
# 是否开启本仓库
enabled=1
# 是否检查 gpg 签名文件
gpgcheck=0
# 是否检查 gpg 签名文件
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装 Containerd

Kubernetes 1.25.0 起取消对 Docker 直接兼容,现用 Containerd 替代。这也是旧版本与 1.25.x 最大差别。 此步骤全部节点执行

cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

# 获取阿里云YUM源
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 下载安装
yum install -y containerd.io

image.png 此步骤全部节点执行

# 生成 containerd 的配置文件
mkdir /etc/containerd -p
# 生成配置文件
containerd config default > /etc/containerd/config.toml
# 编辑配置文件
# vim /etc/containerd/config.toml
# 快速修改
sed -i "s/registry.k8s.io/registry.aliyuncs.com\/google_containers/g" /etc/containerd/config.toml

修 > 改 > 内 > 容 > 如 > 下 ( 默 认 快 速 修 改 可 掠 过 ) >

地址国内要改,k8s源是谷歌,国内用不了

sandbox_image = "k8s.gcr.io/pause:3.6" ↓ sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"

# 启动 containerd
systemctl enable containerd
systemctl start containerd

# 检查启动状况
ps -ef | grep containerd
ps -ef | grep container
ctr version
runc -version

image.png image.png

安装 K8s 1.25x

此步骤全部节点执行 你需要在每台机器上安装以下的软件包:

  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。

关于升级:https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

安装 kubeadm、kubelet、kubectl

此步骤全部节点执行

# 创建 yum 缓存
yum makecache
# 当前 1.25 是最新版,安装最新版,懒得打版本号了,后续有更新加上版本号
yum install -y kubectl kubelet kubeadm
# systemctl enable kubelet

# 设置 kubelet 开机自启(由于没有生成配置文件,集群初始化后自动启动)
systemctl enable kubelet

# 准备k8s1.25.0 所需要的镜像
kubeadm config images list

image.png 注意 这一步在 **MAIN **执行

# 使用 kubeadm init 命令初始化
# 在 主节点 上执行,报错请看k8s报错汇总
# 执行出错使用 kubeadm reset
# 出现 Status from runtime service failed" err="rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
# 找到是 config 导致的问题,使用官方 config 即可
# https://blog.csdn.net/weixin_40668374/article/details/124849090
# rm /etc/containerd/config.toml
# systemctl restart containerd

kubeadm init --apiserver-advertise-address={IP} --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.25.0 --pod-network-cidr=10.224.0.0/16

# --apiserver-advertise-address 集群通告地址(MASTER 的 IP)
# --image-repository 由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址
# --kubernetes-version K8s版本,与上面安装的一致
# --service-cidr 集群内部虚拟网络,Pod统一访问入口
# --pod-network-cidr Pod 网络,与下面部署的CNI网络组件yaml中保持一致
# 更新源? dnf -y upgrade --skip-broken --nobest

若初始化成功,会出现 kubeadm join ... 需要保存 在其他节点执行 kubeadm join ... 加入

检查安装状态

# 按照教程执行 kubectl get node 会出现 The connection to the server localhost:8080 was refused - did you specify the right host or port?
# 根据 k8s 论坛指引生成配置文件即可
# https://discuss.kubernetes.io/t/the-connection-to-the-server-localhost-8080-was-refused-did-you-specify-the-right-host-or-port/1464

# 如果你是普通用户
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 如果你是管理员
# export KUBECONFIG=/etc/kubernetes/admin.conf

kubectl config view
kubectl get node

image.png

集群部署网络插件

注意 这一步在 **MAIN **执行 网络组件有很多种,只需要部署其中一个即可,推荐Calico。 Calico是一个纯三层的数据中心网络方案,Calico支持广泛的平台,包括Kubernetes、OpenStack等。 Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。 此外,Calico 项目还实现了 Kubernetes 网络策略,提供ACL功能。

未安装 Calico 时,使用 kubectl get node 查询节点状态为 notready 安裝之後 node 需要1-5分钟才会 ready

# 下载Calico
wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate
# 编辑配置
vim calico.yaml

# 快速部署
# sed -i "s/# - name: CALICO_IPV4POOL_CIDR/- name: CALICO_IPV4POOL_CIDR/g" calico.yaml
# sed -i "s/# value: \"192.168.0.0\/16\"/ value: \"10.244.0.0\/16\"/g" calico.yaml
# 按 / 输入 CALICO_IPV4POOL_CIDR 查找
# 这里要注意缩进
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"

# 执行
kubectl apply -f calico.yaml
kubectl get pod -n kube-system
kubectl get node

image.png

部署 dashborad

新版本 dashboard describe 默认不给 token,需要 create token。若使用最新版请完全按照教程使用。

# 下载配置文件 (目前最新版本v2.6.1)
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.1/aio/deploy/recommended.yaml
# 挪到方便的位置
mv recommended.yaml /home/recommended.yaml
# 请打开编辑器编辑这个文件

kubectl apply -f ./recommended.yaml

找 到 相 似 的 地 方 并 作 出 更 改

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard
# 创建容器
kubectl apply -f /home/recommended.yaml
# 创建账号
cat <<EOF >/home/admin-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
# 注册用户
kubectl apply -f admin-user.yaml
# 获取 token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
kubectl -n kubernetes-dashboard create token admin-user

打开 ip:30001 输入 token 即可访问 token 容易失效,所以使用 kubectl -n kubernetes-dashboard edit deployments kubernetes-dashboard修改配置,按照如下修改:

spec:
containers:
- args:
- --auto-generate-certificates
- --token-ttl=0 #make the token last forever

保存后生成 token 即可。安全性根据需求自行确定是否需要这一步。

参考文章

官网 https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
Cgroup 驱动 https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/
k8s1.25.x 使用 kubeadm 部署 https://blog.51cto.com/flyfish225/5680876
unknown runtime https://blog.csdn.net/weixin_40668374/article/details/124849090
localhost:8080 refuse 问题 https://discuss.kubernetes.io/t/the-connection-to-the-server-localhost-8080-was-refused-did-you-specify-the-right-host-or-port/1464
CentOS 7 安装配置 k8s 1.25.3 https://blog.csdn.net/qq_32596527/article/details/127606374
k8s集群安装v1.25.0 https://blog.51cto.com/happyshare/5670790
ErrImagePull and ImagePullBackoff https://komodor.com/learn/how-to-fix-errimagepull-and-imagepullbackoff/
部署并使用Docker https://help.aliyun.com/document_detail/264695.html
Anolis OS 7.9安装docker https://blog.csdn.net/weixin_43652442/article/details/124488971
Kubernetes安装与卸载 https://blog.csdn.net/weixin_43652442/article/details/127378479
Dashboard 各种坑 https://blog.csdn.net/weixin_45898119/article/details/126177634

快装脚本

# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# 关闭所有防火墙(使用安全组)
systemctl stop firewalld
systemctl disable firewalld

# 关闭swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 系统优化
cat > /etc/sysctl.d/k8s_better.conf << EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
modprobe br_netfilter
lsmod |grep conntrack
modprobe ip_conntrack
sysctl -p /etc/sysctl.d/k8s_better.conf

# 系统依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset iproute-tc jq iptables curl sysstat libseccomp wget vim net-tools git
# bash 自补充 (阿里云自带,非托管机构自行加料)
# sudo yum -y install bash-completion
# source /etc/profile

# 时间同步,开机启动 (阿里云自带,非托管机自行加料)
# sudo ntpdate ntp1.aliyun.com
# sudo systemctl status ntpdate
# sudo systemctl start ntpdate
# sudo systemctl status ntpdate
# sudo systemctl enable ntpdate

# 关闭 selinux
getenforce
cat /etc/selinux/config
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
cat /etc/selinux/config

# 开启ipvs 转发
modprobe br_netfilter

cat <<EOF >/etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules

bash /etc/sysconfig/modules/ipvs.modules

lsmod | grep -e ip_vs -e nf_conntrack

# 确保每台机器的uuid不一致,如果是克隆机器,修改网卡配置文件删除uuid那一行
cat /sys/class/dmi/id/product_uuid

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
# 是否开启本仓库
enabled=1
# 是否检查 gpg 签名文件
gpgcheck=0
# 是否检查 gpg 签名文件
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

# 获取阿里云YUM源
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 下载安装
yum install -y containerd.io

# 生成 containerd 的配置文件
mkdir /etc/containerd -p
# 生成配置文件
containerd config default > /etc/containerd/config.toml
# 编辑配置文件
sed -i "s/registry.k8s.io/registry.aliyuncs.com\/google_containers/g" /etc/containerd/config.toml

# 启动 containerd
systemctl enable containerd
systemctl start containerd

# 检查启动状况
ps -ef | grep containerd
ps -ef | grep container
ctr version
runc -version

# 创建 yum 缓存
yum makecache
# 当前 1.25 是最新版,安装最新版,懒得打版本号了,后续有更新加上版本号
yum install -y kubectl kubelet kubeadm
# systemctl enable kubelet

# 设置 kubelet 开机自启(由于没有生成配置文件,集群初始化后自动启动)
systemctl enable kubelet

# 准备k8s1.25.0 所需要的镜像
kubeadm config images list

注意 这一步在 **MAIN **执行

# 使用 kubeadm init 命令初始化
# 在 主节点 上执行,报错请看k8s报错汇总
# 执行出错使用 kubeadm reset
# 出现 Status from runtime service failed" err="rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
# 找到是 config 导致的问题,使用官方 config 即可
# https://blog.csdn.net/weixin_40668374/article/details/124849090
# rm /etc/containerd/config.toml
# systemctl restart containerd

kubeadm init --apiserver-advertise-address={IP} --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.25.0 --pod-network-cidr=10.224.0.0/16

# --apiserver-advertise-address 集群通告地址(MASTER 的 IP)
# --image-repository 由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址
# --kubernetes-version K8s版本,与上面安装的一致
# --service-cidr 集群内部虚拟网络,Pod统一访问入口
# --pod-network-cidr Pod 网络,与下面部署的CNI网络组件yaml中保持一致
# 更新源? dnf -y upgrade --skip-broken --nobest

若初始化成功,会出现 kubeadm join ... 需要保存 在其他节点执行 kubeadm join ... 加入 注意 这一步在 **MAIN **执行

export KUBECONFIG=/etc/kubernetes/admin.conf

kubectl config view
kubectl get node

# 下载Calico
wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate

# 编辑配置
sed -i "s/# - name: CALICO_IPV4POOL_CIDR/- name: CALICO_IPV4POOL_CIDR/g" calico.yaml
sed -i "s/# value: \"192.168.0.0\/16\"/ value: \"10.244.0.0\/16\"/g" calico.yaml

# 执行
kubectl apply -f calico.yaml

kubectl get pod -n kube-system
kubectl get node

token 生成与管理、dashboard 请查看“部署 dashboard”。